#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "../tracedef.h"
#include "TraceAst.h"
static S4 traceIfStmt( VOID );
static S4 traceBlockStmt( VOID );
static S4 traceForStmt( VOID );
static S4 traceWhileStmt( VOID );
static S4 traceDoStmt( VOID );
static S4 traceSwitchStmt( VOID );
static S4 traceCaseStmt( VOID );
static S4 traceDefaultStmt( VOID );
static S4 traceDecStmt( VOID );
static S4 traceBreakStmt( VOID );
static S4 traceContinueStmt( VOID );
static S4 traceReturnStmt( VOID );
static S4 traceGotoStmt( VOID );
static S4 traceExpStmt( VOID );
/*   */
/**************************************************************************
 * 関 数 名 :	traceIfStmt
 * 機    能 : 	if文のトレース処理
 * 引 き 数 :	void
 * 戻 り 値 : 	TRACEEXIT_SUCCESS
 * 			TRACEEXIT_FATAL
 * 詳細内容 :
 * 　　前提：
 * 　　　　現在のトレース対象はif文である。
 *　　処理：
 *　　　・実行できない（辿り着けない）場合、スキップする
 * 　　　・スタックのトップは現在のif文じゃない場合、スタックに入れる。
 ************************************************************************/
static S4 traceIfStmt(VOID) {
	AST astTemp = 0;
	AST astMaxstack = 0;
	U2 usTimes = 0;
	/* 戻り値をTRACEEXIT_SUCCESSとする */
	S4 iRc = TRACEEXIT_SUCCESS;
	U2 usRet = 0;

	/* if(STACKの最上テーブル != カレントトレース対象) */
	astMaxstack = stTraceStackAccess.getMax();
	usRet = stTraceStackAccess.kind.get(astMaxstack);
	astTemp = stTraceStackAccess.currObject.get(astMaxstack);
	if (stCurrTraceInfo.astTable != astTemp
			|| stCurrTraceInfo.usKind != usRet) {
		/* if文をSTACKへPUSHする	*/
		iRc = TraceStack(STACK_PUSH);
		if (iRc != TRACEEXIT_SUCCESS) {
			return (iRc);
		}
	}

	/* if(if文的追迹 次数 == 0) */
	astMaxstack = stTraceStackAccess.getMax();
	usTimes = stTraceStackAccess.times.get(astMaxstack);
	if (usTimes == 0) {
		/****************************************
		 * トレース対象更新
		 ****************************************/
		/* トレース対象更新  */
		stCurrTraceInfo.usKind = TR_KIND_EXPRESSION;
		stCurrTraceInfo.astTable = CStatement.if_getCondExp(stCurrTraceInfo.astTable);
		stCurrTraceInfo.astNext = 0;
		/* if文のトレース回数を1とする	*/
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, 1);
	}
	/* else if(if文のトレース回数 == １)	 */
	else if (usTimes == 1) {

		/****************************************
		 * トレース対象更新
		 ****************************************/
		/*カレントトレース対象をif文本体とする		*/
		stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
		stCurrTraceInfo.astTable = CStatement.if_getBody( stCurrTraceInfo.astTable);
		stCurrTraceInfo.astNext = 0;

		/* if文のトレース回数を2とする */
		stTraceStackAccess.times.set(astMaxstack, 2);
	} else if (usTimes == 2) {
		/****************************************
		 * トレース対象更新
		 ****************************************/
		stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
		stCurrTraceInfo.astTable = CStatement.if_getElseBody(
				stCurrTraceInfo.astTable);
		stCurrTraceInfo.astNext = 0;
		/* if文のトレース回数を2とする */
		stTraceStackAccess.times.set(astMaxstack, 3);

	} else {
		/* カレントトレース対象を空とする。 */
		stCurrTraceInfo.astTable = 0;
		stCurrTraceInfo.astNext = 0;
		/* if文のトレース回数を最大回数とする */
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, TRACE_OBJECT_END);
	}

	/*戻り値をreturn*/
	return (TRACEEXIT_SUCCESS);
}

/******************************************************************
 * 関 数 名 : traceForStmt
 * 機    能  : 追迹for文
 * 引    数  : 无
 * 戻 り 値 :	TRACEEXIT_SUCCESS
 * 			TRACEEXIT_FATAL
 * 詳細内容 :
 *******************************************************************/
static S4 traceForStmt(VOID) {
	AST astTemp = 0;
	AST astMaxstack = 0;
	U2 usTimes = 0;
	U2 usRet = 0;

	S4 iRc = TRACEEXIT_SUCCESS;

	astMaxstack = stTraceStackAccess.getMax();
	usRet = stTraceStackAccess.kind.get(astMaxstack);
	astTemp = stTraceStackAccess.currObject.get(astMaxstack);
	if (stCurrTraceInfo.astTable != astTemp
			|| usRet != stCurrTraceInfo.usKind) {
		iRc = TraceStack(STACK_PUSH);
		if (iRc != TRACEEXIT_SUCCESS) {
			return (iRc);
		}
	}
	astMaxstack = stTraceStackAccess.getMax();
	usTimes = stTraceStackAccess.times.get(astMaxstack);
	if (usTimes == 0) {
		/****************************************
		 * トレース対象更新
		 ****************************************/
		stCurrTraceInfo.usKind = TR_KIND_EXPRESSION;
		stCurrTraceInfo.astTable = CStatement.for_getInitExp(
				stCurrTraceInfo.astTable);
		if (stCurrTraceInfo.astTable == 0) {
			stCurrTraceInfo.usKind = TR_KIND_DECLARATION;
			stCurrTraceInfo.astTable = CStatement.for_getInit_Decl(
					stCurrTraceInfo.astTable);

		}
		stCurrTraceInfo.astNext = 0;
		/****************************************
		 * trace回数更新
		 ****************************************/
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, 1);
	}
	else if (usTimes == 1) {
		/****************************************
		 * トレース対象更新
		 ****************************************/
		stCurrTraceInfo.usKind = TR_KIND_EXPRESSION;
		stCurrTraceInfo.astTable = CStatement.for_getCondExp(
				stCurrTraceInfo.astTable);
		stCurrTraceInfo.astNext = 0;
		/****************************************
		 * trace回数更新
		 ****************************************/
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, 2);
	} else if (usTimes == 2) {
		/****************************************
		 * トレース対象更新
		 ****************************************/
		stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
		stCurrTraceInfo.astTable = CStatement.for_getBody(
				stCurrTraceInfo.astTable);
		stCurrTraceInfo.astNext = 0;
		/****************************************
		 * trace回数更新
		 ****************************************/
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, 3);
	}

	else if (usTimes == 3) {
		/****************************************
		 * トレース対象更新
		 ****************************************/
		stCurrTraceInfo.usKind = TR_KIND_EXPRESSION;
		stCurrTraceInfo.astTable = CStatement.for_getIncExp(
				stCurrTraceInfo.astTable);
		stCurrTraceInfo.astNext = 0;
		/****************************************
		 * trace回数更新
		 ****************************************/
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, 4);
	} else {
		/****************************************
		 * トレース対象更新
		 ****************************************/
		stCurrTraceInfo.astTable = 0;
		stCurrTraceInfo.astNext = 0;
		/****************************************
		 * trace回数更新
		 ****************************************/
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, TRACE_OBJECT_END);

	}
	return (TRACEEXIT_SUCCESS);
}

/******************************************************************
* 関 数 名 : traceWhileStmt
* 機    能  : トレースwhile文
* 引    数  : 无
* 戻 り 値 :	TRACEEXIT_SUCCESS
* 			TRACEEXIT_FATAL
* 詳細内容 :
*******************************************************************/
static S4 traceWhileStmt( VOID )
{
	AST astTemp = 0;
	AST astMaxstack = 0;
	U2 usTimes = 0;

	/* 戻り値をTRACEEXIT_SUCCESSとする */
	S4 iRc = TRACEEXIT_SUCCESS;
	U2 usRet = 0;

	astMaxstack = stTraceStackAccess.getMax();
	usRet = stTraceStackAccess.kind.get(astMaxstack);
	astTemp = stTraceStackAccess.currObject.get(astMaxstack);
	if( stCurrTraceInfo.astTable != astTemp || stCurrTraceInfo.usKind != usRet)
	{
		iRc = TraceStack( STACK_PUSH );
		if( iRc != TRACEEXIT_SUCCESS )
		{
			return(iRc);
		}
	}

	astMaxstack = stTraceStackAccess.getMax();
	usTimes = stTraceStackAccess.times.get(astMaxstack);
	if( usTimes == 0 )
	{
		/****************************************
		 * トレース対象更新
		 ****************************************/
		stCurrTraceInfo.usKind = TR_KIND_EXPRESSION;
		stCurrTraceInfo.astTable = CStatement.while_getCondExp( stCurrTraceInfo.astTable );
		stCurrTraceInfo.astNext = 0;
		/****************************************
		 * trace回数更新
		 * ****************************************/
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, 1);
	}
	else if( usTimes == 1 )
	{

		/****************************************
		 * トレース対象更新
		 ****************************************/
	   	/*カレントトレース対象をwhile文本体とする		*/
	   	stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
	   	stCurrTraceInfo.astTable = CStatement.while_getBody( stCurrTraceInfo.astTable );
		stCurrTraceInfo.astNext = 0;
		/****************************************
		 * trace回数更新
		 ****************************************/
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, 2);
	}
	else
	{
		/* カレントトレース対象を空とする。 */
		stCurrTraceInfo.astTable = 0;
		stCurrTraceInfo.astNext = 0;

		/* while文のトレース回数を最大回数とする  */
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, TRACE_OBJECT_END );
	}
	/*戻り値をreturn*/
	return (TRACEEXIT_SUCCESS);

}


/******************************************************************
* 関 数 名 : 	S4 traceGotoStmt( VOID )
* 機    能 : 	トレースgoto文
* 引    数 : 	なし
* 戻 り 値 :	TRACEEXIT_SUCCESS	正常終了
* 		 	TRACEEXIT_FATAL	        致命エラー
* 詳細内容 :
*******************************************************************/
static S4 traceGotoStmt( VOID )
{
	AST astMaxstack;
	U2 usRet;
	AST astTemp;
	S4 iRc;

	astMaxstack = stTraceStackAccess.getMax();
	usRet = stTraceStackAccess.kind.get(astMaxstack);
	astTemp = stTraceStackAccess.currObject.get(astMaxstack);
	if( stCurrTraceInfo.astTable != astTemp || stCurrTraceInfo.usKind != usRet)
	{
		iRc = TraceStack( STACK_PUSH );
		if( iRc != TRACEEXIT_SUCCESS )
		{
			return(iRc);
		}
	}
	/* カレントトレース対象を空とする。 */
	stCurrTraceInfo.astTable = 0;
	stCurrTraceInfo.astNext = 0;

	astMaxstack = stTraceStackAccess.getMax();
	stTraceStackAccess.times.set(astMaxstack, TRACE_OBJECT_END );
	return TRACEEXIT_SUCCESS;
}


/******************************************************************
* 関 数 名 : 	S4 traceLabelStmt( VOID )
* 機    能 : 	トレースgoto文
* 引    数 : 	なし
* 戻 り 値 :	TRACEEXIT_SUCCESS	正常終了
* 		 	TRACEEXIT_FATAL	        致命エラー
* 詳細内容 :
*******************************************************************/
static S4 traceLabelStmt( VOID )
{
//	AST astMaxstack;
//	AST astTemp;

//	astMaxstack = stTraceStackAccess.getMax();
//	astTemp = stTraceStackAccess.currObject.get(astMaxstack);
	/* カレントトレース対象を空とする。 */
	stCurrTraceInfo.astNext = CStatement.getNextStmt( stCurrTraceInfo.astTable );
	stCurrTraceInfo.astTable = CStatement.label_getStatement( stCurrTraceInfo.astTable );
//	astMaxstack = stTraceStackAccess.getMax();
	return TRACEEXIT_SUCCESS;
}

/******************************************************************
* 関 数 名 : 	S4 traceSwitchStmt( VOID )
* 機    能 : 	トレースswitch文
* 引    数 : 	なし
* 戻 り 値 :	TRACEEXIT_SUCCESS	正常終了
* 		 	TRACEEXIT_FATAL	        致命エラー
* 詳細内容 :
*******************************************************************/
static S4 traceSwitchStmt( VOID )
{

	AST astTemp = 0 ;
	U2 usTimes = 0 ;
	AST astMaxstack = 0 ;
	S4 IRC = TRACEEXIT_SUCCESS ; 	/* 戻り値をTRACEEXIT_SUCCESSとする */
	U2 usRet  = 0;

	astMaxstack = stTraceStackAccess.getMax();
	usRet = stTraceStackAccess.kind.get(astMaxstack);
	astTemp = stTraceStackAccess.currObject.get(astMaxstack);
	if( stCurrTraceInfo.astTable != astTemp || usRet != stCurrTraceInfo.usKind )
	{
		/* switch文をSTACKへPUSHする	*/
		IRC = TraceStack( STACK_PUSH );
		if( IRC != TRACEEXIT_SUCCESS )
		{
			return( IRC );
		}
	}
	astMaxstack = stTraceStackAccess.getMax();
	usTimes = stTraceStackAccess.times.get(astMaxstack);
	if( usTimes == 0)
	{
		/* カレントトレース対象をswitch文の制御式とする  */
		stCurrTraceInfo.usKind = TR_KIND_EXPRESSION;
		stCurrTraceInfo.astTable =  CStatement.switch_getCondExp( stCurrTraceInfo.astTable  );
		stCurrTraceInfo.astNext = 0;
		/* switch文のトレース回数を1とする	*/
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, 1 );
	}
	else if ( usTimes == 1 )
	{
		astMaxstack = stTraceStackAccess.getMax();
		astTemp = CStatement.switch_getFirstCase( stCurrTraceInfo.astTable );
		if ( astTemp == 0 )
		{
			/*カレントトレース対象を空とする*/
			stCurrTraceInfo.astNext = 0;
			stCurrTraceInfo.astTable = 0;
			/*switch文のトレース回数を2とする	*/
			astMaxstack = stTraceStackAccess.getMax();
			stTraceStackAccess.times.set(astMaxstack, 2 );
		}
		else
		{
			/*switch文のトレース回数を2とする	*/
			astMaxstack = stTraceStackAccess.getMax();
			stTraceStackAccess.times.set(astMaxstack, 2 );
			/****************************************
			 * トレース対象更新
			 ****************************************/
			/*カレントトレース対象をswitch文の最初のcase文/default文とする	*/
			stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
			stCurrTraceInfo.astTable = astTemp ;
			stCurrTraceInfo.astNext = CStatement.getNextStmt( astTemp );
			IRC = TraceStack( STACK_PUSH );
			if( IRC != TRACEEXIT_SUCCESS )
			{
				return( IRC );
			}
		}
	}
	else if ( usTimes == 2 )
	{
		/*switch文のトレース回数を2とする	*/
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, 3 );
		astMaxstack = stTraceStackAccess.getMax();
		astTemp = CStatement.switch_getDefault( stCurrTraceInfo.astTable );
		if ( astTemp == 0 )
		{
			/*カレントトレース対象を空とする*/
			stCurrTraceInfo.astNext = 0;
			stCurrTraceInfo.astTable = 0;
		}
		else
		{
			/****************************************
			 * トレース対象更新
			 ****************************************/
			/*カレントトレース対象をswitch文の最初のcase文/default文とする	*/
			stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
			stCurrTraceInfo.astTable = astTemp ;
			stCurrTraceInfo.astNext = CStatement.getNextStmt( astTemp );
			IRC = TraceStack( STACK_PUSH );
			if( IRC != TRACEEXIT_SUCCESS )
			{
				return( IRC );
			}
		}
	}
	else
	{
		/*カレントトレース対象を空とする	*/
		stCurrTraceInfo.usKind = 0;
		stCurrTraceInfo.astTable = 0;
		stCurrTraceInfo.astNext = 0;
		/*switch文のトレース回数を最大回数とする*/
		astMaxstack = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set(astMaxstack, TRACE_OBJECT_END );
	}
	return TRACEEXIT_SUCCESS;
}
/******************************************************************
* 関 数 名	 : S4 traceBlockStmt( VOID )
* 機 能：		トレースブロック文
* 引 数：		なし
* 戻り値：		TRACEEXIT_SUCCESS
				TRACEEXIT_FATAL
* 詳細内容 :
*
*******************************************************************/
static S4 traceBlockStmt( VOID )
{
	/* 戻り値をTRACEEXIT_SUCCESSとする	*/
	S4 iRc = TRACEEXIT_SUCCESS;
	AST astLTemp = 0;
	U2 usTemp = 0;
	AST astMaxKind = 0;

	astMaxKind = stTraceStackAccess.getMax();
	usTemp = stTraceStackAccess.kind.get(astMaxKind);
	astLTemp = stTraceStackAccess.currObject.get(astMaxKind);
	if( astLTemp != stCurrTraceInfo.astTable || usTemp != stCurrTraceInfo.usKind )
	{
		/* 	block文をSTACKへPUSHする */
		iRc = TraceStack( STACK_PUSH );
		if( iRc != TRACEEXIT_SUCCESS )
		{
			return iRc;
		}
	}
	astMaxKind = stTraceStackAccess.getMax();
	usTemp = stTraceStackAccess.times.get(astMaxKind);
	if( usTemp == 0 )
	{
		/*	トレース回数変更	ブロック文のトレース回数を1とする  */
		astMaxKind = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set( astMaxKind, 1 );

		/*	カレントトレース対象変更カレントトレース対象をブロック文の一番目の子文とする	*/
		astLTemp = CStatement.block_getChain( stCurrTraceInfo.astTable );
		stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
		stCurrTraceInfo.astTable = astLTemp;
		stCurrTraceInfo.astNext = CStatement.getNextStmt( astLTemp );
	}
	else
	{
		astMaxKind = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set( astMaxKind, TRACE_OBJECT_END );
		/*	カレントトレース対象変更カレントトレース対象を空とする		*/
		stCurrTraceInfo.astTable = 0;
		stCurrTraceInfo.astNext = 0;
	}

	/* 戻り値をreturn	*/
	return TRACEEXIT_SUCCESS;
}
/******************************************************************
* 関 数 名	 : S4 traceDefaultStmt( VOID )
* 機能：	トレースdefault文
* 引数：		なし
* 戻り値：		TRACEEXIT_SUCCESS
			TRACEEXIT_FATAL
* 詳細内容 :
*******************************************************************/
static S4 traceDefaultStmt( VOID )
{
	S4 iRc = 0;
	U2 usTemp = 0;
	AST astLTemp = 0;
	AST astMaxKind = 0;

	/* 戻り値をTRACEEXIT_SUCCESSとする */
	iRc = TRACEEXIT_SUCCESS;

	astMaxKind = stTraceStackAccess.getMax();
	usTemp = stTraceStackAccess.kind.get(astMaxKind);
	astLTemp = stTraceStackAccess.currObject.get(astMaxKind);
	if( astLTemp != stCurrTraceInfo.astTable || usTemp != stCurrTraceInfo.usKind )
	{
		/* カレントトレース対象をnextとする	*/
		stCurrTraceInfo.astNext = CStatement.getNextStmt( stCurrTraceInfo.astTable );
		stCurrTraceInfo.astTable = CStatement.default_getStatement( stCurrTraceInfo.astTable );
		stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
	}
	else
	{
		/*if(default文のトレース回数 == 0)*/
		astMaxKind = stTraceStackAccess.getMax();
		usTemp = stTraceStackAccess.times.get(astMaxKind);
		if( usTemp == 0 )
		{
			/* カレントトレース対象をnextとする */
			stCurrTraceInfo.astTable = CStatement.default_getStatement( stCurrTraceInfo.astTable );
			stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
			stCurrTraceInfo.astNext = CStatement.getNextStmt( stCurrTraceInfo.astTable );

			/* default文のトレース回数を1とする */
			astMaxKind = stTraceStackAccess.getMax();
			stTraceStackAccess.times.set(astMaxKind,1);
		}
		 else
		 {
		 	/*	STACKからPULLする	*/
		 	iRc = TraceStack( STACK_PULL );
			if( iRc != TRACEEXIT_SUCCESS )
			{
				return iRc;
			}
			stCurrTraceInfo.astTable = 0;
			stCurrTraceInfo.astNext = 0;
		 }
	}
	/* 戻り値をreturn	 */
	return TRACEEXIT_SUCCESS;
}



/******************************************************************
* 関 数 名	 : S4 traceDecStmt( VOID )
* 機能：	トレースローカル定義文
* 引数：		なし
* 戻り値：		TRACEEXIT_SUCCESS
			TRACEEXIT_FATAL
* 詳細内容 :
*******************************************************************/
static S4 traceDecStmt( VOID )
{
	S4 iRc = 0;
	AST astDecl = 0;
//	AST astDeclarator = 0;
	U2 usTemp = 0;
	AST astMaxKind = 0;
	AST maxKind;
	/*	戻り値をTRACEEXIT_SUCCESSとする	*/
	iRc = TRACEEXIT_SUCCESS;

	astMaxKind = stTraceStackAccess.getMax();
	usTemp = stTraceStackAccess.kind.get(astMaxKind);
	maxKind = stTraceStackAccess.currObject.get(astMaxKind);
	if( maxKind != stCurrTraceInfo.astTable || usTemp !=  stCurrTraceInfo.usKind )
	{
		iRc = TraceStack( STACK_PUSH );
		if( iRc > TRACEEXIT_WARNING )
		{
			return iRc;
		}
		astMaxKind = stTraceStackAccess.getMax();
		/*debug,12/11/14,S*/
		astDecl = CStatement.dec_getDeclaration( stCurrTraceInfo.astTable );
		/*debug,12/11/14,E*/
		if( astDecl != 0 )
		{
//			astDeclarator = CDeclaration.getDeclarator( astDecl );
			stTraceStackAccess.times.set( astMaxKind, 1 );
			stCurrTraceInfo.usKind = TR_KIND_DECLARATION;
			stCurrTraceInfo.astTable = astDecl;
			stCurrTraceInfo.astNext =  CDeclaration.getNextDeclaration( astDecl );
		}else{
			stTraceStackAccess.times.set( astMaxKind, TRACE_OBJECT_END );
			stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
			stCurrTraceInfo.astNext = CStatement.getNextStmt( stCurrTraceInfo.astTable );
			stCurrTraceInfo.astTable = 0;
		}
	}else{
		astMaxKind = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set( astMaxKind, TRACE_OBJECT_END );

		stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
		stCurrTraceInfo.astNext = CStatement.getNextStmt( stCurrTraceInfo.astTable );
		stCurrTraceInfo.astTable = 0;
	}
	return TRACEEXIT_SUCCESS;
}


/******************************************************************
* 関 数 名	 : S4 traceDoStmt( VOID )
* 機能：	トレースdo文
* 引数：		なし
* 戻り値：		TRACEEXIT_SUCCESS
			TRACEEXIT_FATAL
* 詳細内容 :
*******************************************************************/
static S4 traceDoStmt( VOID )
{
	AST astTemp = 0;
	U2 usTimes = 0;
	AST astMaxKind = 0;
	U2 usRet = 0;
	/* 	戻り値をTRACEEXIT_SUCCESSとする 	*/
	S4 iRc = TRACEEXIT_SUCCESS;

	astMaxKind = stTraceStackAccess.getMax();
	usRet = stTraceStackAccess.kind.get(astMaxKind);
	astTemp = stTraceStackAccess.currObject.get(astMaxKind);
	if( stCurrTraceInfo.astTable != astTemp || stCurrTraceInfo.usKind != usRet )
	{
		iRc = TraceStack( STACK_PUSH );
		if( iRc != TRACEEXIT_SUCCESS )
		{
			return(iRc);
		}
	}

	astMaxKind = stTraceStackAccess.getMax();
	stTraceStackAccess.times.get( astMaxKind );

	if( usTimes == 0 )
	{
		astMaxKind = stTraceStackAccess.getMax();
		/* カレントトレース対象をdo文本体とする */
		stCurrTraceInfo.astTable = CStatement.do_getBody( stCurrTraceInfo.astTable );
		stCurrTraceInfo.astNext = 0;
		/* do文のトレース回数を1とする		 */
		astMaxKind = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set( astMaxKind, 1 );
	}
	else if( usTimes == 1 )
	{
		/* continueもしあれば  */
		stCurrTraceInfo.usKind = TR_KIND_EXPRESSION;
		stCurrTraceInfo.astTable = CStatement.do_getCondExp( stCurrTraceInfo.astTable );

		/* do文のトレース回数を2とする		 */
		astMaxKind = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set( astMaxKind, 2 );
	}
	else
	{
		/* カレントトレース対象を空とする。 */
		stCurrTraceInfo.astTable = 0;
		stCurrTraceInfo.astNext = 0;
		/* for文のトレース回数を最大回数とする  */
		stTraceStackAccess.times.set( astMaxKind, TRACE_OBJECT_END );
	}

	/* 戻り値をreturn	 */
	return TRACEEXIT_SUCCESS;
}


/******************************************************************
* 関 数 名 :traceBreakStmt
* 機    能 : トレースbreak文
* 引    数 : なし
* 戻 り 値 :	TRACEEXIT_SUCCESS
* 		 	TRACEEXIT_FATAL
* 詳細内容 :
*******************************************************************/

static S4 traceBreakStmt( VOID )
{
    stCurrTraceInfo.astNext = 0;
    stCurrTraceInfo.astTable = 0;
    return TRACEEXIT_SUCCESS;
}



/******************************************************************
* 関 数 名 :traceCaseStmt
* 機    能 : トレースcase文
* 引    数 : なし
* 戻 り 値 :	TRACEEXIT_SUCCESS
* 		 	TRACEEXIT_FATAL
* 詳細内容 :
*******************************************************************/

static S4 traceCaseStmt( VOID )
{
	AST astTemp = 0;
	AST astTemp2 = 0;
	U2 usTimes = 0;
	AST astMaxKind = 0;
	U2 usRet = 0;
	S4 iRc = TRACEEXIT_SUCCESS;	/* 戻り値をTRACEEXIT_SUCCESSとする */

	astMaxKind = stTraceStackAccess.getMax();
	usRet = stTraceStackAccess.kind.get(astMaxKind);
	astTemp = stTraceStackAccess.currObject.get(astMaxKind);
	if( stCurrTraceInfo.astTable != astTemp  || usRet != stCurrTraceInfo.usKind )
	{
		/* カレントトレース対象をnextとする */
		stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
		stCurrTraceInfo.astTable =  CStatement.case_getStatement( stCurrTraceInfo.astTable  );
		stCurrTraceInfo.astNext = CStatement.getNextStmt( stCurrTraceInfo.astTable  ) ;
	}
	else
	{
		astMaxKind = stTraceStackAccess.getMax();
		usTimes = stTraceStackAccess.times.get( astMaxKind );
	    if( usTimes == 0)
	    {
	    	/* カレントトレース対象をcase文の定数式とする */
	    	astTemp2 = CStatement.case_getConstExp( astTemp );
	    	astTemp = stCurrTraceInfo.astTable;
	    	stCurrTraceInfo.astTable = astTemp2;
	    	stCurrTraceInfo.usKind = TR_KIND_EXPRESSION;
	    	/* 戻り値＝TraceExp() */
	    	iRc = TraceExp( );
			if ( iRc != TRACEEXIT_SUCCESS )
			{
				return ( iRc );
			}
			/* case文のトレース回数を1とする */
			astMaxKind = stTraceStackAccess.getMax();
			usTimes = stTraceStackAccess.times.set( astMaxKind, 1 );

			/* カレントトレース対象をnextとする */
			stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
			stCurrTraceInfo.astTable = CStatement.case_getStatement( astTemp );
			if ( stCurrTraceInfo.astTable > 0 )
			{
				stCurrTraceInfo.astNext = CStatement.getNextStmt( astTemp  ) ;
			}
	    }
	    else
	    {
	    	/* STACKからPULLする */
	    	iRc = TraceStack( STACK_PULL );
			if( iRc != TRACEEXIT_SUCCESS )
			{
				return( iRc );
			}
			/* case文のトレース回数を最大回数とする */
			astMaxKind = stTraceStackAccess.getMax();
			/* カレントトレース対象を次のcase文/default文とする */
			stCurrTraceInfo.usKind = TR_KIND_STATEMENT;
			stCurrTraceInfo.astTable =  CStatement.case_getNextCase( stCurrTraceInfo.astTable );
			if( stCurrTraceInfo.astTable > 0 )
			{
				stCurrTraceInfo.astNext = CStatement.getNextStmt( stCurrTraceInfo.astTable ) ;
			}
			else
			{
				stCurrTraceInfo.astNext  = 0 ;
			}

			if( stCurrTraceInfo.astTable != 0 )
			{
				iRc = TraceStack( STACK_PUSH );
				if( iRc != TRACEEXIT_SUCCESS )
				{
					return(iRc);
				}
			}
	    }
	}

	/* 戻り値をreturn */
	return TRACEEXIT_SUCCESS;
}



/******************************************************************
* 関 数 名 :traceContinueStmt
* 機    能 : トレースcontinue文
* 引    数 : なし
* 戻 り 値 :	TRACEEXIT_SUCCESS
* 		 	TRACEEXIT_FATAL
* 詳細内容 :
*******************************************************************/

static S4 traceContinueStmt( VOID )
{
	/* カレントトレース対象を空とする。 */
	stCurrTraceInfo.astTable = 0;
	stCurrTraceInfo.astNext = 0;

	/* 戻り値をreturn  */
	return TRACEEXIT_SUCCESS;
}



/******************************************************************
* 関 数 名 : traceExpStmt
* 機    能 : トレース式文
* 引    数 : なし
* 戻 り 値 :TRACEEXIT_SUCCESS
* 		 TRACEEXIT_END
*        TRACEEXIT_FATAL
* 詳細内容 :
*******************************************************************/


static S4 traceExpStmt( VOID )
{
	S4 iRet = 0;                           /* 戻 り 値 */
	AST astMaxKind =0;
	AST astTraceStackUpon = 0;
	U2 usRet = 0;

	iRet = TRACEEXIT_SUCCESS;           /* 初期値設定 */

	astMaxKind = stTraceStackAccess.getMax();
	usRet = stTraceStackAccess.kind.get(astMaxKind);
	astTraceStackUpon = stTraceStackAccess.currObject.get(astMaxKind);
	if( astTraceStackUpon != stCurrTraceInfo.astTable
			|| usRet !=  stCurrTraceInfo.usKind )
	{
		 /*式文をSTACKへPUSHする*/
		iRet = TraceStack( STACK_PUSH );
		if( iRet > TRACEEXIT_WARNING )
		{
			return iRet;
		}
		astMaxKind = stTraceStackAccess.getMax();
		/* 式文のトレース回数を1とする */
		stTraceStackAccess.times.set( astMaxKind, 1 );
		/*カレントトレース対象を式文の式とする*/
		stCurrTraceInfo.usKind = TR_KIND_EXPRESSION;
		stCurrTraceInfo.astTable =  CStatement.expStatement_getExp( stCurrTraceInfo.astTable  );
		stCurrTraceInfo.astNext = 0 ;
	}
	else{
		/*式文のトレース回数をトレース最大回数とする */
		astMaxKind = stTraceStackAccess.getMax();
		stTraceStackAccess.times.set( astMaxKind, TRACE_OBJECT_END );

		/* カレントトレース対象を空とする */
		stCurrTraceInfo.astNext = 0;
		stCurrTraceInfo.astTable = 0;
	}
	/*戻り値をreturn*/
	return TRACEEXIT_SUCCESS;
}

/******************************************************************
* 関 数 名 :traceReturnStmt
* 機    能 : トレースreturn文
* 引    数 : なし
* 戻 り 値 :	TRACEEXIT_SUCCESS
* 		 	TRACEEXIT_FATAL
* 詳細内容 :
*******************************************************************/

static S4 traceReturnStmt( VOID )
{
	/* 戻り値をTRACEEXIT_SUCCESSとする  */
	S4 rc = TRACEEXIT_SUCCESS;
	AST astRet = 0;
	AST astRet2 = 0;
	AST astMaxLine = 0;
	AST astMaxLine2 = 0;
	AST astMinStack = 0;
	AST astSet = 0;
	S4 astCnt = 0;
	S4 notEndFlg = 0;
	U2 usTimes = 0;
	U2 usRet = 0;
	S4 iRet;

	/* if（return文の戻り式あり） */
	astRet = CStatement.return_getExp( stCurrTraceInfo.astTable );
	if ( astRet > 0)
	{
		astMaxLine = stTraceStackAccess.getMax();
		usRet = stTraceStackAccess.kind.get( astMaxLine );
		astRet2 = stTraceStackAccess.currObject.get( astMaxLine );
		if( stCurrTraceInfo.astTable != astRet2 || stCurrTraceInfo.usKind != usRet  )
		{
			rc = TraceStack( STACK_PUSH );
			if( rc != TRACEEXIT_SUCCESS )
			{
				return(rc);
			}
		}

		astMaxLine = stTraceStackAccess.getMax();
		usTimes = stTraceStackAccess.times.get( astMaxLine);
		/* 式のトレース回数 == 0 */
		if( usTimes == 0)
		{
			/* return文のトレース回数を1とする */
			astMaxLine = stTraceStackAccess.getMax();
			usTimes = stTraceStackAccess.times.set( astMaxLine, 1 );

			/* カレントトレース対象をreturn文の戻り式とする */
			stCurrTraceInfo.astTable = astRet;
			stCurrTraceInfo.astNext = 0;
			stCurrTraceInfo.usKind = TR_KIND_EXPRESSION;
			return TRACEEXIT_SUCCESS;
		}
		else
		{
			/* return文のトレース回数を最大回数とする */
			astMaxLine = stTraceStackAccess.getMax();
			usTimes = stTraceStackAccess.times.set( astMaxLine, TRACE_OBJECT_END );
			/* STACKからPULLする */
			rc = TraceStack( STACK_PULL );
			if( rc != TRACEEXIT_SUCCESS )
			{
				return(rc);
			}
		}
	}
	astMaxLine = stTraceStackAccess.getMax();
	astMaxLine2 = stTraceFuncAccess.getMax();
	astMinStack = MIN_ARRAY - 1;

	notEndFlg = 0;
	for( astCnt = astMaxLine; astCnt > astMinStack; astCnt--  )
	{
		/* if（カレントトレース対象の「トレース関数情報テーブル」の「連番」 == 「トレース関数情報テーブル」の最大添字） */
		astSet = stTraceStackAccess.traceFunction.get( astCnt );
		if( astSet != astMaxLine2 )
		{
			break;
		}
		/* if（トレーススタック情報が非文） */
		usRet = stTraceStackAccess.kind.get( astCnt );
		if( usRet != TR_KIND_STATEMENT )
		{
				continue;
		}

		/* switch（スタック情報文の種類） */
		astSet = stTraceStackAccess.currObject.get( astCnt );
		if( CStatement.isIf( astSet ) || CStatement.isSwitch( astSet ) ){
			notEndFlg=1;
			/* カレントトレース対象を空とする */
			stCurrTraceInfo.astTable = 0;
			stCurrTraceInfo.astNext = 0;
			break;
		}else if( CStatement.isFor( astSet ) ){
			notEndFlg=1;
			/* カレントトレース対象を空とする */
			stCurrTraceInfo.astTable = 0;
			stCurrTraceInfo.astNext = 0;
			break;
		}else if( CStatement.isWhile( astSet ) ){
			notEndFlg=1;
			/* カレントトレース対象を空とする */
			stCurrTraceInfo.astTable = 0;
			stCurrTraceInfo.astNext = 0;
			break;
		}else if( CStatement.isDo( astSet ) ){
			/* カレントトレース対象を空とする */
			stCurrTraceInfo.astTable = 0;
			stCurrTraceInfo.astNext = 0;

		}else if( CStatement.isBlock( astSet ) ){
			/* カレントトレース対象を空とする */
			stCurrTraceInfo.astTable = 0;
			stCurrTraceInfo.astNext = 0;
		}

	}
	if( notEndFlg == 0 )   /*本関数トレース終了 */
	{
		astMaxLine = stTraceStackAccess.getMax();
		astMaxLine2 = stTraceFuncAccess.getMax();
		astMinStack = MIN_ARRAY - 1;
		for( astCnt = astMaxLine; astCnt > astMinStack; astCnt--  )
		{
			astSet = stTraceStackAccess.traceFunction.get( astCnt );
			if( astSet != astMaxLine2 )
			{
				break;
			}
			iRet = TraceStack( STACK_PULL );
			if( iRet != TRACEEXIT_SUCCESS )
			{
				return iRet;
			}

		}
		if(lEventSec & EVENT_TRFUNCRET)
		{
//			astMaxLine = stTraceFuncAccess.getMax();
//			astMaxLine = Trace_Get_AST( IDX_TRACE_FUNC, TRACE_FUNCINFO, TRACE_STACKSUBINFO, astMaxLine );
//			astMaxLine = Trace_Get_AST( IDX_TRACE_SYMDEFINFO, KIND_SYMDEFINFO, TRACE_FUNCINFO, astMaxLine );
//			iRet = pfunc( KIND_SYMDEFINFO, astMaxLine ,lEvent | EVENT_TRFUNCRET );
//			if( iRet > TRACEEXIT_WARNING )
//			{
//				return iRet;
//			}
		}
		/*debug,12/11/15,S*/
		//stTraceFuncAccess.alloc(-1);
		/*debug,12/11/15,E*/
		/* カレントトレース対象を空とする */
		stCurrTraceInfo.astTable = 0;
		stCurrTraceInfo.astNext = 0;
	}

	return (TRACEEXIT_SUCCESS);
}
/******************************************************************
* 関 数 名 :TraceStmt
* 機    能 : トレース文情報
* 引    数 : なし
* 戻 り 値 :	TRACEEXIT_SUCCESS
* 		 	TRACEEXIT_FATAL
* 詳細内容 :
*******************************************************************/

S4 TraceStmt( VOID )
{
	S4 iRet;                       /* 戻 り 値 */
	iRet = TRACEEXIT_SUCCESS;       /* 初期値設定 */

	if(lEventSec & EVT_STATEMENT)
	{
		iRet = pfunc( stCurrTraceInfo.usKind, stCurrTraceInfo.astTable , lEvent | EVT_STATEMENT );
		if(iRet> TRACEEXIT_WARNING)
		{
			return(iRet);
		}
	}
	if( CStatement.isExpression( stCurrTraceInfo.astTable )){
	    iRet = traceExpStmt( );
	}else if(CStatement.isLabel( stCurrTraceInfo.astTable )){
	    iRet = traceLabelStmt( );
	}else if(CStatement.isCase( stCurrTraceInfo.astTable )){
	    iRet = traceCaseStmt( );
	}else if(CStatement.isDefault( stCurrTraceInfo.astTable )){
	    iRet = traceDefaultStmt( );
	}else if(CStatement.isBlock( stCurrTraceInfo.astTable )){
	    iRet = traceBlockStmt( );
	}else if(CStatement.isIf( stCurrTraceInfo.astTable )){
	    iRet = traceIfStmt( );
	}else if(CStatement.isSwitch( stCurrTraceInfo.astTable )){
	    iRet = traceSwitchStmt( );
	}else if(CStatement.isFor( stCurrTraceInfo.astTable )){
	    iRet = traceForStmt( );
	}else if(CStatement.isWhile( stCurrTraceInfo.astTable )){
	    iRet = traceWhileStmt( );
	}else if(CStatement.isDo( stCurrTraceInfo.astTable )){
	    iRet = traceDoStmt( );
	}else if(CStatement.isGoto( stCurrTraceInfo.astTable )){
	    iRet = traceGotoStmt( );
	}else if(CStatement.isBreak( stCurrTraceInfo.astTable )){
	    iRet = traceBreakStmt( );
	}else if(CStatement.isContinue( stCurrTraceInfo.astTable )){
	    iRet = traceContinueStmt( );
	}else if(CStatement.isReturn( stCurrTraceInfo.astTable )){
	    iRet = traceReturnStmt( );
	}else if(CStatement.isDecl( stCurrTraceInfo.astTable )){
		iRet = traceDecStmt( );
	}else{
		iRet = TRACEEXIT_WARNING;
	}
	return iRet;
}


AST DLL_EXPORT TraceGetCurrStatement( VOID )
{
	AST astCnt;
	AST astSet;
	AST astMinStack;
	U2 usKind;
	/* トレーススタック情報テーブルの最大添字から検索 */
	astCnt = stTraceStackAccess.getMax();
	astMinStack = MIN_ARRAY - 1;
	for( ; astCnt > astMinStack; astCnt-- )
	{
		/* if（スタック情報が非文） */
		usKind = stTraceStackAccess.kind.get( astCnt );
		if( usKind != TR_KIND_STATEMENT )
		{
			continue;
		}
		/* スタック情報文の種類*/
		astSet = stTraceStackAccess.currObject.get( astCnt );
		return astSet;
	}
	return 0;
}
